Skip to content

fix(mcp-worker): restore dynamic client registration endpoint - #581

Merged
jonathannorris merged 4 commits into
mainfrom
fix/restore-mcp-dcr-577
Aug 5, 2026
Merged

fix(mcp-worker): restore dynamic client registration endpoint#581
jonathannorris merged 4 commits into
mainfrom
fix/restore-mcp-dcr-577

Conversation

@jonathannorris

@jonathannorris jonathannorris commented Jul 27, 2026

Copy link
Copy Markdown
Member

Summary

  • Re-adds clientRegistrationEndpoint: '/oauth/register' to the remote MCP worker's OAuthProvider config, reverting Remove unused registration endpoint. #577.
  • Adds a strict Content-Security-Policy to the OAuth consent page so client-supplied metadata can never lead to script execution.

The Problem

#577 removed the registration endpoint as unused. It wasn't: @cloudflare/workers-oauth-provider implements RFC 7591 Dynamic Client Registration automatically whenever clientRegistrationEndpoint is set, and DCR is the only registration mechanism our server offers. Removing it dropped registration_endpoint from /.well-known/oauth-authorization-server and left /oauth/register returning 404.

MCP clients try pre-registered credentials, then CIMD, then DCR (spec). We support none of the first two, so clients fall through to DCR, find no registration_endpoint, and the MCP TypeScript SDK throws from registerClient():

SDK auth failed: Incompatible auth server: does not support dynamic client registration

That's the error users hit on claude mcp add --transport http devcycle https://mcp.devcycle.com/mcp (and npx mcp-remote) since #577 landed. The Claude Code MCP docs call it out by name.

Confirmed against production:

$ curl -s https://mcp.devcycle.com/.well-known/oauth-authorization-server
{... "client_id_metadata_document_supported":false}   # no registration_endpoint

$ curl -s -o /dev/null -w '%{http_code}' -X POST https://mcp.devcycle.com/oauth/register
404

Securing the consent page

DCR lets any client register a client_name / logo_uri, which the consent page reflects on devcycle.com. Rather than rely on output escaping alone, this makes script execution impossible there:

Content-Security-Policy: script-src 'none'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'

The page has no first-party JavaScript (static HTML, inline <style>, a <form>), so script-src 'none' costs nothing and blocks inline <script>, injected onerror/onload handlers, and mutation-XSS variants, independently of escaping. Verified locally by registering a malicious client_name and loading the consent page: header present, page renders normally, name emitted as inert escaped text.

Related

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 27, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
devcycle-mcp-server 3eafec4 Aug 05 2026, 03:31 PM

@jonathannorris
jonathannorris marked this pull request as ready for review July 27, 2026 18:01
@jonathannorris
jonathannorris requested a review from a team as a code owner July 27, 2026 18:01
Copilot AI review requested due to automatic review settings July 27, 2026 18:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Restores OAuth Dynamic Client Registration support in the remote MCP worker by reintroducing the clientRegistrationEndpoint option on the Cloudflare Workers OAuth provider, so MCP clients that rely on RFC 7591 can obtain a client_id again.

Changes:

  • Re-adds clientRegistrationEndpoint: '/oauth/register' to the OAuthProvider configuration.
  • Adds an in-code comment explaining why the registration endpoint is required (notably for Claude Code / mcp-remote).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jonathannorris
jonathannorris force-pushed the fix/restore-mcp-dcr-577 branch from 6ddd1b3 to 68eaeaf Compare July 28, 2026 19:41
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
@jonathannorris
jonathannorris force-pushed the fix/restore-mcp-dcr-577 branch from c38653e to 3eafec4 Compare August 5, 2026 15:27
@jonathannorris
jonathannorris enabled auto-merge (squash) August 5, 2026 15:27
@jonathannorris
jonathannorris merged commit b945ba8 into main Aug 5, 2026
6 of 7 checks passed
@jonathannorris
jonathannorris deleted the fix/restore-mcp-dcr-577 branch August 5, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants